package tool

import (
	"GoServer/utils/debug"
	"bytes"
	"crypto/aes"
	"crypto/cipher"
	"crypto/md5"
	"crypto/rand"
	"encoding/base64"
	"fmt"
	"math/big"
	"reflect"
	"time"
)

var key = GenerateKey("Jiushuhudongyouxi_online")

// / 加密数据
func CryptEncrypt(content string) (string, error) {
	// 原始数据
	plaintext := content

	tempBlock, err := aes.NewCipher(key)
	if err != nil {
		debug.Logln(debug.Info, "Error creating AES cipher:", err)
		return "", err
	}
	// 使用 AES 加密块创建一个加密模式
	mode := cipher.NewCBCEncrypter(tempBlock, key)
	// 填充数据
	plaintext = string(Pkcs7Pad([]byte(plaintext), aes.BlockSize))
	// 加密数据
	ciphertext := make([]byte, len(plaintext))
	mode.CryptBlocks(ciphertext, []byte(plaintext))

	// 将加密结果进行 base64 编码
	encryptedBase64 := base64.StdEncoding.EncodeToString(ciphertext)
	return encryptedBase64, nil
}

// pkcs7Pad 实现 PKCS7 填充
func Pkcs7Pad(data []byte, blockSize int) []byte {
	padding := blockSize - len(data)%blockSize
	padText := bytes.Repeat([]byte{byte(padding)}, padding)
	return append(data, padText...)
}

// pkcs7Unpad 移除 PKCS7 填充
func Pkcs7Unpad(data []byte) []byte {
	padding := int(data[len(data)-1])
	return data[:len(data)-padding]
}

// 解密数据
func CryptDecrypt(base64Str []byte) ([]byte, error) {
	decodedBytes, err := base64.StdEncoding.DecodeString(string(base64Str))
	if err != nil {
		debug.Logln(debug.Error, "Error decoding:", err)
		return nil, err
	}
	ciphertext := decodedBytes
	debug.Logln(debug.Info, "解密后的原始数据："+string(ciphertext))

	// 创建一个 AES 加密块
	block, err := aes.NewCipher(key)
	if err != nil {
		debug.Logln(debug.Error, "Error creating AES cipher:", err)
		return nil, err
	}

	// 使用 AES 加密块创建一个加密模式
	mode := cipher.NewCBCEncrypter(block, key)

	// 解密数据
	decrypted := make([]byte, len(ciphertext))
	mode = cipher.NewCBCDecrypter(block, key)
	mode.CryptBlocks(decrypted, ciphertext)

	// 移除填充
	decrypted = Pkcs7Unpad(decrypted)

	// 将解密后的字节切片转换为字符串
	decryptedString := bytes.NewBuffer(decrypted).String()
	debug.Logln(debug.Info, "解密后的数据："+decryptedString)

	return []byte(decryptedString), nil
}

// / 异常判断
// / recover捕获
func InterfaceIsNil(value interface{}) bool {
	ret := value == nil

	if !ret {
		defer func() {
			recover()
		}()
		ret = reflect.ValueOf(value).IsNil()
	}

	return ret
}

// generateKey 使用 MD5 哈希函数生成 16 字节密钥
func GenerateKey(input string) []byte {
	// 创建一个 MD5 哈希对象
	hash := md5.New()

	// 将原始字符串转换为字节并进行哈希
	hash.Write([]byte(input))

	// 获取哈希结果，并截取前 16 个字节作为密钥
	return hash.Sum(nil)[:16]
}

const letterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"

// 生成随机字符串
func randString(n int) string {
	b := make([]byte, n)
	for i := range b {
		// 随机从 letterBytes 中选择一个字符
		num, _ := rand.Int(rand.Reader, big.NewInt(int64(len(letterBytes))))
		b[i] = letterBytes[num.Int64()]
	}
	return string(b)
}

func GenerateUniqueID(end string) string {
	// 获取当前时间戳的前10位（秒）
	timestamp := time.Now().Unix()

	// 获取当前时间的毫秒部分
	millis := time.Now().UnixNano() / int64(time.Millisecond)

	// 将时间戳和毫秒数组合为字符串，并限制长度
	timePart := fmt.Sprintf("%010d", timestamp)[:10] + fmt.Sprintf("%03d", millis%1000)[:3]

	// 生成 5 位的随机字母数字组合
	randomPart := randString(5)

	// 返回总长度为18位的唯一 ID
	return timePart + randomPart + end
}
